/**
 * Created by Void on 2017/9/8.
 */

import {
    Component,
    ChangeDetectorRef,
    Renderer2,
    OnInit,
    Input,
    Output,
    EventEmitter,
    ViewChild,
    ViewChildren,
    QueryList
} from '@angular/core';

import {} from '@angular/forms';
import {stringify} from "@angular/core/src/util";

@Component({
    selector: 'tags-input',
    template: `
<div [class]="'ion-tags-input tit-border-color ' + (readonly ? 'readonly' : color)" [class.active]="_isFocus">
<span #tags *ngFor="let tag of _tags; let $index = index;" [class]="'iti-tag iti-tag-color ' + color + ' iti-tag-'+ mode">
{{tag}}
<a [hidden]="hideRemove || readonly" class="iti-tag-rm" (click)="btnRemoveTag($index)"></a>
</span>
<input #tagsInput class="iti-input"
[hidden]="readonly"
[disabled]="readonly"
[type]="type"
[placeholder]="placeholder"
[(ngModel)]="_editTag"
(blur)="_blur()"
(focus)="_focus()"
(keyup.backspace)="keyRemoveTag($event)"
(keyup)="separatorStrAddTag()"
(keyup.enter)="keyAddTag()"
/>
</div>`
})

export class TagsInputComponent implements OnInit {

    _editTag:string = '';
    _tags:string[] = [];
    _isFocus:boolean = false;
    _colors = ['#4a8bfc', '#32db64', '#f53d3d', '#ffc125', '#767676', '#7e60ff', '#222', '#bcbcbc'];


    @ViewChild('tagsInput') input:any;
    @ViewChildren('tags') tags:QueryList<any>;

    @Input() mode:string = 'ios';
    @Input() readonly:boolean = false;
    @Input() color:string = '';
    @Input() hideRemove:boolean = false;
    @Input() once:boolean = true;
    @Input() maxTags:number = -1;
    @Input() separetorStr:string = ',';
    @Input() canEnterAdd:boolean = true;
    @Input() canBackspaceRemove:boolean = true;
    @Input() verifyMethod:(tagStr:string) => boolean;

    @Input() text:string = 'text';
    @Input() placeholder:string = 'afei';

    @Output() onChange = new EventEmitter<string[]>();

    constructor(public ref:ChangeDetectorRef,
                protected renderer:Renderer2) {
    }

    ngOnInit() {
        console.log(this.mode);
    }

    keyRemoveTag() {
        if (!this.canBackspaceRemove) return;
        if (this._editTag === ''){
            this.removeTag(-1);
            this._editTag = '';
        }
    }

    removeTag(index:number):any{
        if (this._tags.length > 0){
            if (index === -1){
                this._tags.pop();
                this.onChange.emit(this._tags);
            }else if (index > -1){
                this._tags.splice(index,1);
                this.onChange.emit(this._tags);
            }
        }
    }

    separatorStrAddTag() {
        const lastIndex:number = this._editTag.length-1;
        let tagStr:string = '';
        if (!this.separetorStr) return;

        if (this._editTag[lastIndex] === this.separetorStr){
            tagStr = this._editTag.split(this.separetorStr)[0].trim();

            if (this.verifyTag(tagStr) && this.isOnce(tagStr)){
                this.pushTag(tagStr);
            }else {
                this._editTag = '';
            }
        }

    }

    keyAddTag() {
        let tagStr = this._editTag.trim();
        if (!this.canEnterAdd) return;
        if (!this.verifyTag(tagStr)) return;
        if (!this.isOnce(tagStr)) {
            this._editTag = '';
            return;
        }
        this.pushTag(tagStr);
    }

    btnRemoveTag(index:number):any{
        this.input.nativeElement.blur();
        this.removeTag(index)
    }


    // 判断外界(外部使用的组件,需要实现 verifyMethod 方法)那些规定的字符串不能生成 tag
    verifyTag(tagStr:string):boolean {
        if (typeof this.verifyMethod === 'function') {
            if (!this.verifyMethod(tagStr)) {
                this._editTag = '';
                return false;
            } else {
                return true;
            }
        }

        if (!tagStr.trim()) {
            this._editTag = '';
            return false;
        } else {
            return true;
        }
    }

    // 根据 once 属性 来判断 是否可以生成重复的tag default:true
    isOnce(tagStr:string):boolean {
        if (!this.once) return true;
        const tags:string[] = this._tags;
        return tags.every((e:string):boolean => {
            return e !== tagStr;
        })
    }

    pushTag(tagStr:string):any {
        if (this.maxTags !== -1 && this._tags.length >= this.maxTags) {
            this._editTag = '';
            return;
        }
        this._tags.push(tagStr.trim());
        this.ref.detectChanges();
        this.addRandomColor();
        this.onChange.emit(this._tags);
        this._editTag = '';
    }


    addRandomColor() {
        if (this.color !== 'random') return;
        let tagsEve = this.tags.toArray();
        this.renderer.setStyle(tagsEve[tagsEve.length-1].nativeElement,'backgroundColor',this.getRandomColor());
    }

    private getRandomColor(){
        const max = this._colors.length + 1;
        let index = Math.floor(Math.random() * max);
        return this._colors[index];
    }

    private _focus() {
        this._isFocus = true;
    }

    private _blur() {
        this.input.nativeElement.blur();
        this._isFocus = false;
    }

}